﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using AForge.Imaging;
using System.Net;
using System.ComponentModel;
using System.Windows.Controls.DataVisualization.Charting;
using System.Collections.ObjectModel;

namespace KinectGestureRecognition.ObjectDetection
{
    /// <summary>
    /// Interaktionslogik für ObjectDetectorWindow.xaml
    /// </summary>
    public partial class ObjectDetectorWindow : Window, INotifyPropertyChanged
    {
        #region constructor
        public ObjectDetectorWindow()
        {
            InitializeComponent();
            this.DataContext = this;
            this.LocalImagePath= "D:\\+++DropBox+++\\Dropbox\\+++ projekt +++\\+++Kinect+++\\KinectGestureRecognition\\KinectGestureRecognition\\Sample.jpg";
            this.ksm = KinectSensorModul.Instance;
            ksm.OnColorstreamReadyEvent += new KinectSensorModul.ColorStreamReadyEvent(ksm_OnColorstreamReadyEvent);
            ksm.OnDepthFrameReadyEvent += new KinectSensorModul.DepthFrameReadyEvent(ksm_OnDepthFrameReadyEvent);
            this._ObjectDetectionStream = new DepthStreamObjectDetection();
            this._ObjectDetectionStream.OnDepthStreamOperation += new Interfaces.DepthStreamStrategy.DepthStreamOperationEvent(_ObjectDetectionStream_OnDepthStreamOperation);
            
        }

      

        void ksm_OnDepthFrameReadyEvent(object sender, Microsoft.Kinect.DepthImageFrame depthImageFrame)
        {
            _ObjectDetectionStream.PerformDepthStreamOperation(sender, depthImageFrame);
        }
   
        #endregion

        #region INotifyPropertyChanged implementation

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Private variables
        private KinectSensorModul ksm;
        private String localImagePath = null;
        private PointCollection _luminanceHistogramPoints = null;
        private PointCollection _redColorHistogramPoints = null;
        private PointCollection _greenColorHistogramPoints = null;
        private PointCollection _blueColorHistogramPoints = null;
        private PointCollection _depthHistogram = null;
        private ImageSource _colorStream;
        private BitmapImage bi;
        private Interfaces.DepthStreamStrategy _ObjectDetectionStream;
        #endregion

        #region Public Properties

        public ChartingCollectionInt Data { get; set; }

        public String ImageURL { get; set; }

        public String LocalImagePath
        {
            get
            {
                return this.localImagePath;
            }
            set
            {
                if (this.localImagePath != value)
                {
                    this.localImagePath = value;
                    if (this.PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("LocalImagePath"));
                    }
                }
            }
        }

        public bool PerformHistogramSmoothing { get; set; }

        public PointCollection LuminanceHistogramPoints
        {
            get
            {
                return this._luminanceHistogramPoints;
            }
            set
            {
                if (this._luminanceHistogramPoints != value)
                {
                    this._luminanceHistogramPoints = value;
                    if (this.PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("LuminanceHistogramPoints"));
                    }
                }
            }
        }

        public PointCollection RedColorHistogramPoints
        {
            get
            {
                return this._redColorHistogramPoints;
            }
            set
            {
                if (this._redColorHistogramPoints != value)
                {
                    this._redColorHistogramPoints = value;
                    if (this.PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("RedColorHistogramPoints"));
                    }
                }
            }
        }

        public PointCollection GreenColorHistogramPoints
        {
            get
            {
                return this._greenColorHistogramPoints;
            }
            set
            {
                if (this._greenColorHistogramPoints != value)
                {
                    this._greenColorHistogramPoints = value;
                    if (this.PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("GreenColorHistogramPoints"));
                    }
                }
            }
        }

        public PointCollection BlueColorHistogramPoints
        {
            get
            {
                return this._blueColorHistogramPoints;
            }
            set
            {
                if (this._blueColorHistogramPoints != value)
                {
                    this._blueColorHistogramPoints = value;
                    if (this.PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("BlueColorHistogramPoints"));
                    }
                }
            }
        }

        public PointCollection DepthHistogramPoints
        {
            get
            {
                return this._depthHistogram;
            }
            set
            {
                if (this._depthHistogram != value)
                {
                    this._depthHistogram = value;
                    if (this.PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("DepthHistogramPoints"));
                    }
                }
            }
        }

        public ImageSource ColorStream
        {
            get { return _colorStream; }
            set 
            {
                if (this._colorStream != value)
                {
                    this._colorStream = value;
                    if (this.PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("ColorStream"));
                    }
                }            
            }
        }

        #endregion

        #region subscribed Events
        void _ObjectDetectionStream_OnDepthStreamOperation(object sender)
        {
            this.ColorStream = ((Interfaces.DepthStreamStrategy)sender).bitmapSource;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {

            //this.chart1.DataContext = "2,3,4,5,";


            //bi = new BitmapImage();
            //bi.BeginInit();
            //String path = "D:\\+++DropBox+++\\Dropbox\\+++ projekt +++\\+++Kinect+++\\KinectGestureRecognition\\KinectGestureRecognition\\Sample2.jpg";
            //bi.UriSource = new Uri(path, UriKind.Absolute);
            //bi.EndInit();
            //imageJPG.Source = bi;


            LocalImagePath = "D:\\+++DropBox+++\\Dropbox\\+++ projekt +++\\+++Kinect+++\\KinectGestureRecognition\\KinectGestureRecognition\\Sample2.jpg";
            using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(LocalImagePath))
            {
                // Luminance
                ImageStatisticsHSL hslStatistics = new ImageStatisticsHSL(bmp);
                this.LuminanceHistogramPoints = ConvertToPointCollection(hslStatistics.Luminance.Values);
                // RGB
                ImageStatistics rgbStatistics = new ImageStatistics(bmp);
                this.RedColorHistogramPoints = ConvertToPointCollection(rgbStatistics.Red.Values);
                this.GreenColorHistogramPoints = ConvertToPointCollection(rgbStatistics.Green.Values);
                this.BlueColorHistogramPoints = ConvertToPointCollection(rgbStatistics.Blue.Values);
            }
            //Polygon p = new Polygon();
            //p.Points = LuminanceHistogramPoints;

            //this.LuminosityBorder.Child = p.Points.t; 
        }

        void ksm_OnColorstreamReadyEvent(object sender, BitmapSource colorFrame)
        {
           // this.imageColorStream.Source = colorFrame;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

        }
        #endregion

        #region Helper Functions
        private PointCollection ConvertToPointCollection(int[] values)
        {
            if (this.PerformHistogramSmoothing)
            {
                values = SmoothHistogram(values);
            }

            int max = values.Max();

            PointCollection points = new PointCollection();
            // first point (lower-left corner)
            points.Add(new Point(0, max));
            // middle points
            for (int i = 0; i < values.Length; i++)
            {
                points.Add(new Point(i, max - values[i]));
            }
            // last point (lower-right corner)
            points.Add(new Point(values.Length - 1, max));

            return points;
        }

        private int[] SmoothHistogram(int[] originalValues)
        {
            int[] smoothedValues = new int[originalValues.Length];

            double[] mask = new double[] { 0.25, 0.5, 0.25 };

            for (int bin = 1; bin < originalValues.Length - 1; bin++)
            {
                double smoothedValue = 0;
                for (int i = 0; i < mask.Length; i++)
                {
                    smoothedValue += originalValues[bin - 1 + i] * mask[i];
                }
                smoothedValues[bin] = (int)smoothedValue;
            }

            return smoothedValues;
        }
        #endregion





    }



  


}
